package email;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.AuthenticationFailedException;
import javax.mail.Authenticator;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Part;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import javax.mail.URLName;  

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.*; 


public class EmailSender implements IMail {
	public Logger logger = null;
	private String host;
	private String port;
	private String from;
	private String to;
	private String title;
	private String content;
	private List<File> attachmentlist = new ArrayList<File>();
	private String username;
	private String password;
	private String sendEmployeeId;
	
	public String getHost() {
		return host;
	}
	public void setHost(String host) {
		this.host = host;
	}
	public String getPort() {
		return port;
	}
	public void setPort(String port) {
		this.port = port;
	}
	public String getFrom() {
		return from;
	}
	public void setFrom(String from) {
		this.from = from;
	}
	public String getTo() {
		return to;
	}
	public void setTo(String to) {
		this.to = to;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public List<File> getAttachmentlist() {
		return attachmentlist;
	}
	public void setAttachmentlist(List<File> attachmentlist) {
		this.attachmentlist = attachmentlist;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getSendEmployeeId() {
		return sendEmployeeId;
	}
	public void setSendEmployeeId(String sendEmployeeId) {
		this.sendEmployeeId = sendEmployeeId;
	}
	
	public EmailSender(String host, String from, String to, String title, String content,
			List<File> attachmentlist, String username, String password, String port)
	{
		//获得当前目录路径   
        String filePath=this.getClass().getResource("/").getPath();   
        //找到log4j.properties配置文件所在的目录(已经创建好)   
        filePath=filePath.substring(1).replace("bin", "src");   
        //获得日志类logger的实例   
        logger = Logger.getLogger(EmailSender.class);
        //logger所需的配置文件路径   
        //PropertyConfigurator.configure(filePath+"log4j.properties"); 
		this.host = host;  
        this.from = from;  
        this.to = to;  
        this.title = title;  
        this.content = content;  
        this.attachmentlist = attachmentlist;  
        this.username = username;  
        this.password = password;  
        this.port=port;  
	}
	
	public EmailSender(String to, String title, String content, List attachmentlist) {  
        this.to = to;  
        this.title = title;  
        this.content = content;  
        this.attachmentlist = attachmentlist;  
    }
	
	public void addAttachments(File file) {
		attachmentlist.add(file);
	}
	
	public String[] sendMail() {
		String[] result = new String[2];
		Session session = null;
		Properties props = System.getProperties();
		props.put("mail.smtp.host", host);
		props.put("mail.smtp.sendpartial", "true");
		props.put("mail.smtp.prot", port);
		
		if (StringUtils.isBlank(username)) {
			session = Session.getDefaultInstance(props, null);
		} else {
			props.put("mail.smtp.auth", "true");
			EmailAuthenticator auth = new EmailAuthenticator(username, password);
			session = Session.getInstance(props, auth);
		}
		
		try {
			MimeMessage message = new MimeMessage(session);
			message.setFrom(new InternetAddress(from));
			InternetAddress[] toAddr = InternetAddress.parse(to);
			message.addRecipients(Message.RecipientType.TO, toAddr);
			message.setSubject(title);
			message.setSentDate(new Date());
			Multipart multipart = new MimeMultipart();
			MimeBodyPart contentPart = new MimeBodyPart();
			contentPart.setText(content);
			multipart.addBodyPart(contentPart);
			
			if (attachmentlist != null && attachmentlist.size() > 0) {
				for (int i = 0; i < attachmentlist.size(); i++) {
					MimeBodyPart attachmentPart = new MimeBodyPart();
					
					FileDataSource source = new FileDataSource(attachmentlist.get(i));
					attachmentPart.setDataHandler(new DataHandler(source));
					attachmentPart.setFileName(MimeUtility.encodeWord(attachmentlist.get(i).getName(), "gb2312", null));
					multipart.addBodyPart(attachmentPart);
				}
			}
			message.setContent(multipart);
			
			if (StringUtils.isBlank(username)) {
				Transport.send(message);
			} else {
				Transport transport = session.getTransport("smtp");
				transport.connect();
				transport.sendMessage(message, message.getAllRecipients());
				transport.close();
			}
			
			result[0] = "0";
			result[1] = "发送成功";
			
			logger.info("邮件发送成功!发送人: " + from);
		} catch (MessagingException mex) {
			result[0] = "1";
			result[1] = "邮件服务器发生错误";
			
			if (mex instanceof AuthenticationFailedException) {
				result[1] = "用户名或密码错误";
			}
		} catch (Exception e) {
			result[0] = "1";
			result[1] = "系统异常";
		}
		
		return result;
	}
	
	public String[] sendFile(File file) {
		attachmentlist.clear();
		attachmentlist.add(file);
		return sendMail();
	}
	public void receiveMail() {
		try {
			Properties props = new Properties();
			props.setProperty("mail.smtp.host", "smtp.163.com");
			props.setProperty("mail.smtp.auth", "true");
			Session session = Session.getDefaultInstance(props);
			
			URLName urlname = new URLName("pop3", "pop.163.com", 110, null, "15626819107@163.com", "@a123456");
			Store store = session.getStore(urlname);
			store.connect();
			Folder folder = store.getDefaultFolder();
			if (folder == null) {
				System.out.println("the server is not available");
				return;
			}
			
			Folder popFolder = folder.getFolder("INBOX");
			popFolder.open(Folder.READ_WRITE);
			Message[] messages = popFolder.getMessages();
			int msgCount = popFolder.getMessageCount();
			System.out.println("Total " + msgCount + " emails.");
			for (int i = 0; i < msgCount; i++) {
				System.out.println("第" + i + "邮件开始");
				mailReceiver(messages[i]);
				System.out.println("第" + i + "邮件结束");
				messages[i].writeTo(new FileOutputStream("D:/pop3MailReceiver"+ i +".eml"));
			}
			popFolder.close(true);
			store.close();
		} catch (NoSuchProviderException e) {
			e.printStackTrace();
		} catch( Exception e) {
			e.printStackTrace();
		}
	}
	
	private void mailReceiver(Message msg) throws Exception {
		Address[] froms = msg.getFrom();
		if (froms != null) {
			InternetAddress addr = (InternetAddress)froms[0];
			System.out.println("发件人地址:" + addr.getAddress());
			System.out.println("发件人显示名:" + addr.getPersonal());
		}
		System.out.println("邮件主题:" + msg.getSubject());
		
		Object o = msg.getContent();
		if (o instanceof Multipart) {
			Multipart multipart = (Multipart) o;
			reMultipart(multipart);
		} else if (o instanceof Part) {
			Part part = (Part) o;
			rePart(part);
		} else {
			System.out.println("类型" + msg.getContentType());
			System.out.println("内容:" + msg.getContent());
		}
	}
	
	private void rePart(Part part) throws MessagingException, UnsupportedEncodingException,
	        IOException, FileNotFoundException {
		if (part.getDisposition() != null) {
			String strFileName = MimeUtility.decodeText(part.getFileName());
			System.out.println("发现附件: " + MimeUtility.decodeText(part.getFileName()));
			System.out.println("附件类型: " + MimeUtility.decodeText(part.getContentType()));
			System.out.println("附件内容: " + part.getContent());
			
			InputStream in = part.getInputStream();
			FileOutputStream out = new FileOutputStream(strFileName);
			int data;
			while ((data = in.read()) != -1) {
				out.write(data);
			}
			in.close();
			out.close();
		} else {
			if (part.getContentType().startsWith("text/plain")) {
				System.out.println("文本内容：" + part.getContent()); 
			} else {
				System.out.println("HTML内容：" + part.getContent());
			}
		}
	}
	
	private void reMultipart(Multipart multipart) throws Exception {
		for (int j = 0, n = multipart.getCount(); j < n; j++) {
			Part part = multipart.getBodyPart(j);
			if (part.getContent() instanceof Multipart) {
				Multipart p = (Multipart)part.getContent();
				reMultipart(p);
			} else {
				rePart(part);
			}
		}
	}

}

class EmailAuthenticator extends Authenticator {
	private String username = null;
	private String password = null;
	
	public EmailAuthenticator(String username, String password) {
		this.username = username;
		this.password = password;
	}
	
	public PasswordAuthentication getPasswordAuthentication() {
		return new PasswordAuthentication(username, password);
	}
}
